home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / -archivi / -recent2 / chunky_dev.lha / chunky_dev / Source / chunkyp2c.asm < prev    next >
Assembly Source File  |  1998-12-28  |  8KB  |  387 lines

  1. ;------------------------------------------------------------------------------
  2. ;
  3. ; 100% systemfriendly PlanarToChunky converter for use with intuition
  4. ; screens in applications/games/whatever.
  5. ;
  6. ; Coded in 1994 by Morten Eriksen.
  7. ; Reach me through email: mortene@stud.unit.no.
  8. ;
  9. ; Use and modify as you like - give credit where appropriate.
  10. ;
  11. ; Timings on my A1200 with 68EC020 and 32-bit fastram:
  12. ;
  13. ;  Testcase    Dimensions       This routine             C='s ReadPixelArray8
  14. ;
  15. ;    1    320x256x5 -    10 frames (0.20 seconds)    41 frames
  16. ;    2    320x256x8 -    16 frames (0.32 seconds)    51 frames
  17. ;    3    640x512x4 -    34 frames (0.68 seconds)    158 frames
  18. ;    4     1024x1024x1 -    35 frames (0.70 seconds)    312 frames
  19. ;    5    752x578x8 -    89 frames (1.78 seconds)    312 frames
  20. ;
  21. ; Please suggest speed-ups in the code if you see any (by changing the
  22. ; algorithm, using other instructions with less executiontime, better
  23. ; pipelining, etc etc). The 'convert32pixels' is of course the bottleneck,
  24. ; as this subroutine accounts for almost all processing done in the
  25. ; converter.
  26. ;
  27. ; Some modifications (stack use instead global data, no 68000 support) in
  28. ; 1998 by Stephan Rupprecht
  29. ;
  30. ;------------------------------------------------------------------------------
  31.     xdef    PlanarToChunkyAsm
  32. ;------------------------------------------------------------------------------
  33. ; This routine takes a buffer of chunkybytes and fills it with converted
  34. ; planar datas from the source BitMap.
  35. ;
  36. ; As a replacement for C='s ReadPixelArray8 routine, this one is more than
  37. ; three times as fast (in worst case) and works directly on bitmaps (instead
  38. ; of RastPorts). All cases handled (any width and height > 0, no alignment
  39. ; restrictions). Works on OCS/ECS/AGA, all Kickstarts and any MC680x0 CPU.
  40. ; The downside is that it does not do clipping and does not work with
  41. ; interleaved bitmaps (support for interleaved bitmaps should be piece of
  42. ; cake to implement, though).
  43. ;------------------------------------------------------------------------------
  44. ;
  45. ; C interface:
  46. ;
  47. ; extern void __asm PlanarToChunkyAsm(register __a0 struct p2cStruct *);
  48. ;
  49. ; struct p2cStruct
  50. ; {
  51. ;  struct BitMap *bmap;
  52. ;  UWORD startX, startY, width, height;
  53. ;  UBYTE *chunkybuffer;
  54. ; } p2c;
  55. ;
  56. ; p2c.bmap = mybitmap;
  57. ; p2c.startX = x0;
  58. ; p2c.startY = y0;
  59. ; p2c.width = x1 - x0 + 1;
  60. ; p2c.height = y1 - y0 + 1;
  61. ; p2c.chunkybuffer = chunkybytes;
  62. ;
  63. ; SyncSBitMap(mywindow->RPort->Layer);
  64. ; PlanarToChunkyAsm(&p2c);
  65. ;------------------------------------------------------------------------------
  66. ;
  67. ; Assembler interface:
  68. ;
  69. ; In:     a0 - p2c struct.
  70. ; Out:    Nothing.
  71. ;------------------------------------------------------------------------------
  72.  
  73. ; ** BitMap struct **
  74. BytesPerRow    EQU    0    ; UWORD
  75. Rows        EQU    2    ; UWORD
  76. Flags        EQU    4    ; UBYTE
  77. Depth        EQU    5    ; UBYTE
  78. Pad        EQU    6    ; UWORD
  79. Planes        EQU    8    ; PLANEPTRs [8]
  80.  
  81. ; ** p2c struct **
  82.  
  83. bmap        EQU    0    ; struct BitMap *
  84. startX        EQU    4    ; UWORD
  85. startY        EQU    6    ; UWORD
  86. width        EQU    8    ; UWORD
  87. height        EQU    10    ; UWORD
  88. chunkybuffer    EQU    12    ; UBYTE *
  89.  
  90. ; **
  91.  
  92. buffer        EQU    0
  93. lastplaneptr    EQU    32
  94. Width        EQU    36
  95. Height        EQU    38
  96. Modulo        EQU    40
  97. leftpix        EQU    42
  98. rightpix    EQU    44
  99. insidebyte    EQU    46
  100. depth        EQU    48
  101. sizeof_buffer    EQU    52
  102.  
  103. ;------------------------------------------------------------------------------
  104.     Section code,CODE
  105.     
  106. PlanarToChunkyAsm:
  107.     movem.l    d2-d7/a2-a6,-(sp)
  108.     
  109.     lea.l    -sizeof_buffer(sp),sp
  110.  
  111.     lea.l    madetable(pc),a2
  112.     tst.b    (a2)        * need only make bitspreadtable on first call
  113.     bne.s    table_made
  114.  
  115. * makes the bitspread table *
  116. * Do not destroy a0! *
  117. make_table:
  118.     lea    p2c,a1
  119.     moveq    #0,d0
  120. more_table
  121.     move.b    d0,d1
  122.  
  123.     moveq    #8-1,d2
  124. byteloop
  125.     btst    #7,d1
  126.     beq.s    zero
  127.     move.b    #1,(a1)+
  128.     bra.s    one
  129. zero    clr.b    (a1)+
  130. one    add.b    d1,d1
  131.     dbra    d2,byteloop
  132.  
  133.     addq    #1,d0
  134.     cmp.w    #256,d0
  135.     beq.s    table_done
  136.     bra.s    more_table
  137. table_done
  138.     move.b    #1,(a2)
  139.  
  140. table_made
  141.  
  142.     move.l    bmap(a0),a1
  143.     move.l    chunkybuffer(a0),a3
  144.     lea    p2c,a4
  145.  
  146.     moveq    #0,d1
  147.     move.w    startX(a0),d0
  148.     andi.w    #%111,d0
  149.     tst.w    d0
  150.     beq.s    noleftpix
  151.     moveq    #8,d1
  152.     sub.w    d0,d1
  153. noleftpix
  154.     move.w    d1,leftpix(sp)
  155.  
  156.     move.w    width(a0),d0
  157.     move.w    d0,Width(sp)
  158. hit    cmp.w    d1,d0
  159.     bhs.s    notinsidebyte
  160.     move.b    #1,insidebyte(sp)
  161.     moveq    #0,d1
  162.     bra.s    isinside
  163.  
  164. notinsidebyte
  165.     clr.b    insidebyte(sp)
  166.     move.w    Width(sp),d0
  167.     sub.w    leftpix(sp),d0
  168.     move.w    d0,d1
  169.     lsr.w    #5,d0
  170.     lsl.w    #5,d0
  171.     sub.w    d0,d1
  172. isinside
  173.     move.w    d1,rightpix(sp)
  174.  
  175.     * find initial offset in bytes into bitmap given by (startX, startY)
  176.     moveq    #0,d0
  177.     move.w    startX(a0),d0
  178.     lsr.w    #3,d0
  179.     move.w    startY(a0),d1
  180.     tst.w    d1
  181.     beq.s    line0
  182.     moveq    #0,d2
  183.     move.w    BytesPerRow(a1),d2
  184.     subq    #1,d1
  185. makeoffset
  186.     add.l    d2,d0
  187.     dbra    d1,makeoffset
  188. line0    move.l    d0,a2
  189.  
  190.     tst.w    leftpix(sp)
  191.     beq.s    nol1
  192.     subq    #3,a2
  193.  
  194. nol1    move.w    Width(sp),d0
  195.     sub.w    rightpix(sp),d0
  196.     move.w    BytesPerRow(a1),d1
  197.     lsr.w    #3,d0
  198.     sub.w    d0,d1
  199.     move.w    d1,Modulo(sp)
  200.  
  201.     tst.b    insidebyte(sp)
  202.     bne.s    nol2
  203.     tst.w    leftpix(sp)
  204.     beq.s    nol2
  205.     subq    #4,Modulo(sp)
  206. nol2
  207.  
  208.     move.w    height(a0),Height(sp)
  209.  
  210.     ; a0 - c2p struct, a1 - bmap,
  211.     ; a2 - offset from Planes pointer, a3 - chunkybuffer
  212.     ; a4 - bitspread table
  213.  
  214.     move.l    a1,a6
  215.     add.w    #Planes,a6
  216.     moveq    #0,d0
  217.     move.b    Depth(a1),d0
  218.     move.w    d0,depth(sp)
  219.     lsl.w    #2,d0
  220.     add.l    d0,a6
  221.     move.l    a6,lastplaneptr(sp)
  222.  
  223. convertline
  224.     tst.b    insidebyte(sp)
  225.     beq.s    notinsidesinglebyte
  226.     bsr.w    convert32pixels
  227.     lea    buffer+32(sp),a5
  228.     movem.l    d0-d7,-(a5)
  229.     moveq    #32,d0
  230.     sub.w    leftpix(sp),d0
  231.     add.l    d0,a5
  232.     move.w    Width(sp),d0
  233.     subq    #1,d0
  234. singleinsert
  235.     move.b    (a5)+,(a3)+
  236.     dbra    d0,singleinsert
  237.     bra.w    linedone
  238.  
  239. notinsidesinglebyte
  240.     tst.w    leftpix(sp)
  241.     beq.s    noleftpixels
  242.  
  243.     tst.w    Width(sp)
  244.     beq.w    linedone
  245.  
  246.     bsr.w    convert32pixels
  247.     lea    buffer+32(sp),a5
  248.     movem.l    d0-d7,-(a5)
  249.     moveq    #32,d0
  250.     sub.w    leftpix(sp),d0
  251.     add.l    d0,a5
  252.     move.w    leftpix(sp),d0
  253.     move.w    d0,d1
  254.     subq    #1,d0
  255. leftinsert
  256.     move.b    (a5)+,(a3)+
  257.     dbra    d0,leftinsert
  258.     sub.w    d1,Width(sp)
  259.     addq    #4,a2
  260.     
  261. noleftpixels
  262.     cmp.w    #32,Width(sp)
  263.     blo.s    trailbits
  264.  
  265.     bsr.w    convert32pixels
  266.  
  267. flushall
  268.     add.w    #32,a3
  269.     movem.l    d0-d7,-(a3)
  270.     add.w    #32,a3
  271.  
  272. nolongflush
  273.     sub.w    #32,Width(sp)
  274.     addq    #4,a2
  275.     bra.b    noleftpixels
  276.  
  277. trailbits
  278.     tst.w    Width(sp)
  279.     beq.s    linedone
  280.  
  281.     bsr.b    convert32pixels
  282.     lea    buffer+32(sp),a5
  283.     movem.l    d0-d7,-(a5)
  284.     move.w    rightpix(sp),d0
  285.     subq    #1,d0
  286. rightinsert
  287.     move.b    (a5)+,(a3)+
  288.     dbra    d0,rightinsert
  289.  
  290. linedone
  291.     move.w    width(a0),Width(sp)
  292.     add.w    Modulo(sp),a2
  293.     subq    #1,Height(sp)
  294.     tst.w    Height(sp)
  295.     bne.w    convertline
  296.  
  297.     lea.l    sizeof_buffer(sp),sp
  298.  
  299.     movem.l    (sp)+,d2-d7/a2-a6
  300.     rts
  301.  
  302. madetable    dc.w    0
  303.  
  304. ;------------------------------------------------------------------------------    
  305.  
  306.     cnop    0,8
  307.  
  308. convert32pixels:
  309.     move.l    a3,-(sp)
  310.     move.l    a0,-(sp)
  311.     move.w    depth+12(sp),a3
  312.     move.l    lastplaneptr+12(sp),a6
  313.     
  314.     move.l    -(a6),a5
  315.     add.l    a2,a5
  316.     clr.w    d7
  317.     move.b    (a5)+,d7
  318.     lsl.w    #3,d7
  319.     movem.l    0(a4,d7.w),d0/d1
  320.     clr.w    d7
  321.     move.b    (a5)+,d7
  322.     lsl.w    #3,d7
  323.     movem.l    0(a4,d7.w),d2/d3
  324.     clr.w    d7
  325.     move.b    (a5)+,d7
  326.     lsl.w    #3,d7
  327.     movem.l    0(a4,d7.w),d4/d5
  328.     clr.w    d7
  329.     move.b    (a5)+,d7
  330.     lsl.w    #3,d7
  331.     movem.l    0(a4,d7.w),d6/d7
  332.  
  333. convert32pixelsloop
  334.     subq.w    #1,a3
  335.     cmp.w    #0,a3
  336.     beq.s    done
  337.  
  338.     move.l    -(a6),a5
  339.     add.l    a2,a5
  340.     move.w    d7,a0
  341.     clr.w    d7
  342.     move.b    (a5)+,d7
  343.     lsl.w    #3,d7
  344.     add.l    d0,d0
  345.     or.l    0(a4,d7.w),d0
  346.     add.l    d1,d1
  347.     or.l    4(a4,d7.w),d1
  348.     clr.w    d7
  349.     move.b    (a5)+,d7
  350.     lsl.w    #3,d7
  351.     add.l    d2,d2
  352.     or.l    0(a4,d7.w),d2
  353.     add.l    d3,d3
  354.     or.l    4(a4,d7.w),d3
  355.     clr.w    d7
  356.     move.b    (a5)+,d7
  357.     lsl.w    #3,d7
  358.     add.l    d4,d4
  359.     or.l    0(a4,d7.w),d4
  360.     add.l    d5,d5
  361.     or.l    4(a4,d7.w),d5
  362.     move.w    a0,d7
  363.     move.w    d5,a0
  364.     clr.w    d5
  365.     move.b    (a5)+,d5
  366.     lsl.w    #3,d5
  367.     add.l    d6,d6
  368.     or.l    0(a4,d5.w),d6
  369.     add.l    d7,d7
  370.     or.l    4(a4,d5.w),d7
  371.     move.w    a0,d5
  372.     bra.s    convert32pixelsloop
  373.  
  374. done    move.l    (sp)+,a0
  375.     move.l    (sp)+,a3
  376.     rts
  377.  
  378. ;------------------------------------------------------------------------------
  379.     Section    tables,BSS    
  380.  
  381.     cnop    0,8
  382. * bitspread table *
  383. p2c    ds.b    256*8
  384.  
  385. ;------------------------------------------------------------------------------
  386.     END
  387.